package com.example.gateway.examples;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.Arrays;
import java.util.List;

/**
 * 自定义过滤器示例
 * 
 * 功能说明：
 * 1. 演示如何创建全局过滤器
 * 2. 展示过滤器链的执行顺序
 * 3. 提供请求处理和响应修改示例
 * 
 * @author Spring Cloud Demo
 * @version 1.0
 * @since 2024-01-01
 */
@Component
public class CustomFilterExample implements GlobalFilter, Ordered {

    private static final Logger logger = LoggerFactory.getLogger(CustomFilterExample.class);

    /**
     * 白名单路径
     */
    private static final List<String> WHITE_LIST = Arrays.asList(
            "/api/health",
            "/api/public/**",
            "/api/actuator/**"
    );

    /**
     * 过滤器执行方法
     * 
     * @param exchange 服务器Web交换对象
     * @param chain 过滤器链
     * @return Mono<Void> 异步处理结果
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        String path = request.getPath().value();
        
        logger.info("🔍 自定义过滤器处理请求: {} {}", request.getMethod(), path);
        
        // 检查白名单
        if (isWhiteListPath(path)) {
            logger.info("✅ 白名单路径，跳过处理: {}", path);
            return chain.filter(exchange);
        }
        
        // 示例1：请求头验证
        String apiKey = request.getHeaders().getFirst("X-API-Key");
        if (apiKey == null || apiKey.isEmpty()) {
            logger.warn("❌ 缺少API Key: {}", path);
            return unauthorized(exchange, "缺少API Key");
        }
        
        // 示例2：请求参数验证
        String version = request.getQueryParams().getFirst("version");
        if (version == null || version.isEmpty()) {
            logger.warn("❌ 缺少版本参数: {}", path);
            return badRequest(exchange, "缺少版本参数");
        }
        
        // 示例3：添加自定义请求头
        ServerHttpRequest modifiedRequest = request.mutate()
                .header("X-Processed-By", "CustomFilter")
                .header("X-Request-Timestamp", String.valueOf(System.currentTimeMillis()))
                .build();
        
        logger.info("✅ 请求验证通过，继续处理: {}", path);
        
        // 继续执行过滤器链
        return chain.filter(exchange.mutate().request(modifiedRequest).build());
    }

    /**
     * 获取过滤器执行顺序
     * 
     * @return 执行顺序
     */
    @Override
    public int getOrder() {
        return -200; // 高优先级
    }

    /**
     * 检查是否为白名单路径
     * 
     * @param path 请求路径
     * @return true表示是白名单路径
     */
    private boolean isWhiteListPath(String path) {
        return WHITE_LIST.stream().anyMatch(whitePath -> {
            if (whitePath.endsWith("/**")) {
                String prefix = whitePath.substring(0, whitePath.length() - 2);
                return path.startsWith(prefix);
            }
            return path.equals(whitePath);
        });
    }

    /**
     * 返回未授权响应
     * 
     * @param exchange 服务器Web交换对象
     * @param message 错误消息
     * @return Mono<Void> 异步处理结果
     */
    private Mono<Void> unauthorized(ServerWebExchange exchange, String message) {
        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
        exchange.getResponse().getHeaders().add("X-Error-Message", message);
        return exchange.getResponse().setComplete();
    }

    /**
     * 返回错误请求响应
     * 
     * @param exchange 服务器Web交换对象
     * @param message 错误消息
     * @return Mono<Void> 异步处理结果
     */
    private Mono<Void> badRequest(ServerWebExchange exchange, String message) {
        exchange.getResponse().setStatusCode(HttpStatus.BAD_REQUEST);
        exchange.getResponse().getHeaders().add("X-Error-Message", message);
        return exchange.getResponse().setComplete();
    }
} 